
var MapUtil = {};

MapUtil.isCollision = function(rect1, rect2){
	// 点碰撞
	if(!rect1.width && !rect1.height){
		var pos = rect1;
		if(pos.x>=rect2.x && pos.x<=rect2.x+rect2.width && pos.y>=rect2.y && pos.y<=rect2.y+rect2.height){
			return true;
		}
		return false;
	}
	// 矩形
	if(Math.abs(rect1.x-rect2.x)<(rect1.width/2+rect2.width/2) && Math.abs(rect1.y-rect2.y)<(rect1.height/2+rect2.height/2)){
		return true;
	}
	return false;
}

MapUtil.contain = function(smallRect, bigRect){
	return smallRect.x > bigRect.x && smallRect.x + smallRect.width < bigRect.x + bigRect.width 
			&& smallRect.y > bigRect.y && smallRect.y + smallRect.height < bigRect.y + bigRect.height;
}

// 获得标记图标('√'号)
MapUtil.getMarkIcon = function(x, y, width, height){
	var pathStr = "M"+x+" "+(y+height/2)
	+"L"+(x+width/2)+" "+(y+height)
	+"L"+(x+width)+" "+y
	+"L"+(x+width/2)+" "+(y+height*0.8)
	+"z";
	return pathStr;
}

function Place(parentId, width, height, bgImg){
	this.parentId = parentId;
	this.record = false;
	this.pathString = null;
	this.width = width;
	this.height = height;
	
	this.bgImg = bgImg;
}

Place.prototype.startRecordPath = function(){
	this.record = true;
}

Place.prototype.stopRecordPath = function(){
	this.record = false;
}

Place.prototype.getPath = function(){
	return this.pathString;
}

Place.prototype.closePath = function(){
	this.pathString += "z";
	this.drawPath(this.pathString);
}

Place.prototype.clearPath = function(){
	this.pathString=null;
	this._pathView.remove();
	this._pathView = null;
}

Place.prototype.newPathPoint = function(x, y){
	if(this.pathString==null){
		this.pathString = "M"+x+" "+y;
		return this.pathString+" L"+(x+1)+" "+y +" L"+(x+1)+" "+(y+1) +" L"+x+" "+(y+1) +"z";
	}
	if(this.pathString.length>=2 && this.pathString.charAt(this.pathString.length-1)=='z'){
		this.pathString = this.pathString.substr(0, this.pathString.length-1);
	}
	this.pathString += ' L'+x+' '+y;
	return this.pathString;
}

Place.prototype.drawPath = function(pathString){
	if(!this._pathView){
		this._pathView = this.paper.path("");
		this._pathView.attr({"stroke":"#123", "fill":"#C00"});
	}
	this._pathView.attr("path", pathString);
}

Place.prototype.setPathListen = function(){
	var oThis = this;
	
	var redrawPath = function(e){
		if(!oThis.record){
			return;
		}
		var pos = DomUtil.getOffset(e, this.container);
		var x = pos.offsetX;
		var y = pos.offsetY;
		
		var pathString = oThis.newPathPoint(x, y);
		oThis.drawPath(pathString);
	}
	
	EventUtil.addEvent(this.container, 'click', redrawPath);
}

Place.prototype.display = function(){
	var parent = document.getElementById(this.parentId);
	var div = document.createElement('div');
	var style = "width:"+this.width+"px; height:"+this.height+"px; margin:0 auto; border:1px solid #00f;";
	if(this.bgImg){
		style += ' background-image:url('+this.bgImg+');background-repeat:no-repeat;';
		//style += ' background-size:'+this.width+'px '+this.height+'px;';
	}
	div.setAttribute('style', style);
	parent.appendChild(div);
	
	this.container = div;
	this.paper = Raphael(this.container, this.width, this.height);
	this.setPathListen();
}

function SubRegion(){
	this.items = [];
}

function Cell(){
}

Cell.prototype.repaint = function(){
	var cellRect;
	if(this.isGridItem){
		cellRect = this.parent.getCellRect(this.rowNum, this.colNum, this);
	}else{
		cellRect = this;
	}
	var x = this.parent.cellWidth + cellRect.x;
	var y = this.parent.cellHeight + cellRect.y;
	var w = cellRect.width;
	var h = cellRect.height;
	
	var border = Math.max(1, Math.floor(w/30));
	var radius = Math.min(w, h)/5;
	
	this.draw(x, y, w, h, radius, border);
}

Cell.prototype.draw = function(x, y, w, h, radius, border){
	var attrs = {'stroke-dash':true, 'stroke-color':"#000066", 'stroke-width':border};
	attrs["fill-color"] = this.selected?"#EE0000":'#FFFFFF';
	this.parent._drawRect(x, y, w, h, radius, attrs);
	this.parent._drawText(x+(w*0.35), y+(h*0.6), this.colNum); //TOTO 字体大小	
}

Cell.prototype.dispose = function(){}

function AbstractArea(parentId, width, height){
	this.itemMap = {};
	this.subRegions = null;
	
	//有效区域的大小
	this.width = width;
	this.height = height;
	this.maxWidth = Number.MAX_VALUE; //控件的最大宽度
	this.maxHeight = Number.MAX_VALUE;//控件的最大高度
	//grid
	this.grideModel = true;
	this.cellWidth = 20;
	this.cellHeight = 20;
	this.cellPadding = 2;

	//容器
	this.parentId = parentId;
	this.container = null;
	this.canvasBox = null;
	
	//标尺
	this.yRuler = [];
	this.xRuler = [];

	this.onselect = null;
}

// 成员的最大坐标和行列
AbstractArea.prototype.getMaxPos = function(){
	var pos = {};
	for(id in this.itemMap){
		var cell = this.itemMap[id];
		if(!pos.xTo || (cell.x+cell.width) > pos.xTo){
			pos.xTo = cell.x;
		}
		if(!pos.yTo || (cell.y+cell.height) > pos.yTo){
			pos.yTo = cell.y;
		}
		if(cell.isGridItem){
			if(!pos.rowNum || cell.rowNum > pos.rowNum){
				pos.rowNum = cell.rowNum;
			}
			if(!pos.colNum || cell.colNum > pos.colNum){
				pos.colNum = cell.colNum;
			}
		}
	}
	return pos;
}

//参考单元格的大小，把整个区域划分成多个小区域
AbstractArea.prototype.getSubRegions = function(){
	if(!this.subRegions){
		this.subRegions = [];
		var cellWidth = this.cellWidth;
		var cellHeight = this.cellHeight;
		var validWidth = this.width;
		var validHeight = this.height;
		var cols = Math.floor(validWidth/cellWidth);
		var rows = Math.floor(validHeight/cellHeight);
		validWidth = cellWidth*cols;
		validHeight = cellHeight*rows;
		var regCols = Math.sqrt(cols);//开平方
		var regRows = Math.sqrt(rows);
		regCols = Math.ceil(regCols);
		regRows = Math.ceil(regRows);
		
		var rw = regCols*cellWidth;
		var rh = regRows*cellHeight;
		
		var x = 0;
		var y = 0;
		
		for(; y < validHeight; ){
			for(; x < validWidth; ){
				var region = new SubRegion();
				region.x = x;
				region.y = y;
				region.width = rw;
				region.height = rh;
				this.subRegions.push(region);
				
				this._drawRect(cellWidth+region.x, cellHeight+region.y, region.width, region.height, 0, {'stroke-color':"#00f"});
				
				x += rw;
			}
			x = 0;
			y += rh;
		}
		
		//other
		var region = new SubRegion();
		region.x = 0;
		region.y = 0;
		region.width = 9999;
		region.height = 9999;
		this.subRegions.push(region);
	}
	return this.subRegions;
}

AbstractArea.prototype.getSubRegions2 = function(){
	if(!this.subRegions){
		var cellWidth = this.cellWidth;
		var cellHeight = this.cellHeight;
		var validWidth = this.width;
		var validHeight = this.height;
		this.subRegions = [];
		var cols = Math.floor(validWidth/cellWidth);
		var rows = Math.floor(validHeight/cellHeight);
		cols = Math.sqrt(cols);//开平方
		rows = Math.sqrt(rows);
		cols = Math.ceil(cols);
		rows = Math.ceil(rows);
		Js.log('cols='+cols+',rows='+rows);
		var rw = Math.ceil(validWidth/cols);
		var rh = Math.ceil(validHeight/rows);
		for(var i=0;i<cols;i++){
			for(var j=0;j<rows;j++){
				var region = new SubRegion();
				region.x = i*rw;
				region.y = j*rh;
				region.width = rw;
				region.height = rh;
				this.subRegions.push(region);
				
				this._drawRect(cellWidth+region.x, cellHeight+region.y, region.width, region.height, 0, {'stroke-color':"#00f"});
			}
		}
	}
	return this.subRegions;
}

AbstractArea.prototype.checkCollision = function(rect){
	var result = false;
	var subRegions = this.getSubRegions();
	for(var i=0;i<subRegions.length;i++){
		var region = subRegions[i];
		if(MapUtil.isCollision(rect, region)){
			for(var j=0;j<region.items.length;j++){
				var cell = region.items[j];
				if(MapUtil.isCollision(cell, rect)){
					result = true;
					break;
				}
			}
		}
	}
	return result;
}

AbstractArea.prototype.getPointItem = function(pos){
	var result = null;
	var subRegions = this.getSubRegions();
	for(var i=0;i<subRegions.length;i++){
		var region = subRegions[i];
		if(MapUtil.isCollision(pos, region)){
			for(var j=0;j<region.items.length;j++){
				var item = region.items[j];
				if(MapUtil.isCollision(pos, item)){
					result = item;
					break;
				}
			}
		}
	}
	return result;
}

AbstractArea.prototype.addToGrid = function(newCell, rowNum, colNum, checkCollision){
	var cellRect = this.getCellRect(rowNum, colNum, newCell);
 	if(checkCollision && this.checkCollision(cellRect)){
 		return false;
 	}
 	newCell.id = AbstractArea.idseq++;
 	newCell.rowNum = rowNum;
 	newCell.colNum = colNum;
 	newCell.isGridItem = true;
	this.add(newCell);
	
	return true;
}

AbstractArea.prototype.add = function(item){
	this.itemMap[item.id] = item;
	item.parent = this;
	
	var subRegions = this.getSubRegions();
	for(var i=0;i<subRegions.length;i++){
		var region = subRegions[i];
		if(MapUtil.isCollision(item, region)){
			region.items.push(item);
			item.regionIndex = i;
			break;
		}
	}
}

/**
* 填满表格
*/
AbstractArea.prototype.fillItems = function(Clazz, attrs){
	var cellWidth = this.cellWidth;
	var cellHeight = this.cellHeight;
	var validWidth = this.width;
	var validHeight = this.height;
	var row = 1;
	var col = 1;
	var cell;

	var xEdge = cellWidth; //验证x坐标是否超过了边界
	var yEdge = cellHeight;
	for(;yEdge <= validHeight; row++){
		for(;xEdge <= validWidth; col++){
			cell = new Clazz();
			BeanUtil.copyProperties(attrs, cell);
			var ok = this.addToGrid(cell, row, col, true);
			xEdge += cellWidth;
		}
		col = 1;
		xEdge = cellWidth;
		yEdge += cellHeight;
	}
}

/*
 * 根据行列得到在grid中的坐标和长宽
 * 起始行列是1,1
 */
AbstractArea.prototype.getCellRect = function(rowNum, colNum, item){
	rowNum-=1;
	colNum-=1;
	var x = this.cellWidth*colNum + this.cellPadding;
	var y = this.cellHeight*rowNum + this.cellPadding;
	var w = this.cellWidth - this.cellPadding*2;
	var h = this.cellHeight - this.cellPadding*2;
	var rect = {
			x : x,
			y : y,
			width : w,
			height : h
		};
	if(item){
		BeanUtil.copyProperties(rect, item);	
	}
	return rect;
}

AbstractArea.prototype.remove = function(item){
	var region = this.subRegions[item.regionIndex];
	for(var i=0;i<region.items.length;i++){
		if(region.items[i].id==item.id){
			region.items.splice(i,1);
		}
	}
	
	delete this.itemMap[item.id];
	item.dispose();
}

AbstractArea.prototype.removeAll = function(item){
	this.itemMap = {};
	this.subRegions = null;
}

AbstractArea.prototype.getSelected = function(selRect){
	var cellArray = [];

	for(id in this.itemMap){
		var cell = this.itemMap[id];
		if(cell && MapUtil.contain(cell, selRect)){
			cellArray.push(cell);
		}
	}
	
	return cellArray;
}

AbstractArea.prototype.zoom = function(rate){
	var max = this.getMaxPos();
	
	this.cellWidth = this.cellWidth*rate;
	this.cellHeight = this.cellHeight*rate;
	this.cellPadding = this.cellPadding*rate;
	
	if(rate>1){
		this.cellWidth = Math.floor(this.cellWidth);
		this.cellHeight = Math.floor(this.cellHeight);
		this.cellPadding = Math.floor(this.cellPadding);
	}else{
		this.cellWidth = Math.ceil(this.cellWidth);
		this.cellHeight = Math.ceil(this.cellHeight);
		this.cellPadding = Math.ceil(this.cellPadding);
	}
	
	this.width = max.colNum*this.cellWidth;
	this.height = max.rowNum*this.cellHeight;
	
	this.repaint();
}

AbstractArea.idseq = 1;

AbstractArea.prototype.createElement = function(){
	if(!this.canvasBox){
		var parent = document.getElementById(this.parentId);
		this.container = DomUtil.newElement('div', {id:'map-container', style:'position: relative; padding:0px; margin:0; border:none;'}, parent);
		this.canvasBox = DomUtil.newElement('div', {id:'map-canvas-box', style:'position: relative; padding:0px; margin:0; border:none;'}, this.container);
		this._setListener();
	}
	
	var canvasWidth = this.width +this.cellWidth*2;
	var canvasHeight = this.height + this.cellHeight*2;

	this.canvasBox.style.width = (canvasWidth+'px');
	this.canvasBox.style.height = (canvasHeight+'px');
	
	var ctw = canvasWidth + 5;
	var cth = canvasHeight + 5;
	if(ctw<=this.maxWidth){
		this.container.style.width = (ctw+'px');	
	}
	if(ctw<=this.maxHeight){
		this.container.style.height = (cth+'px');	
	}
}

AbstractArea.prototype.drawRuler = function(){
	var sl = this.container.scrollLeft;
	var st = this.container.scrollTop;
	
	var colNum = 0;
	var xEdge = this.width + this.cellWidth;
	for(var x=this.cellWidth; x+this.cellWidth<=xEdge; x += this.cellWidth){
		var box = this.xRuler[colNum];
		if(!box){
			box = this._drawTextBox('top');
			this.xRuler[colNum] = box;
		}
		colNum++;
		var rect = this.getCellRect(1, colNum+1);
		rect.y += st;
		this._setTextBox(box, rect, colNum);
	}
	while(this.xRuler.length>colNum){
		DomUtil.removeElement(this.xRuler.pop());
	}

	var rowNum = 0;
	var yEdge = this.height+this.cellHeight;
	for(var y = this.cellHeight; y+this.cellHeight<=yEdge; y += this.cellHeight){
		var box = this.yRuler[rowNum];
		if(!box){
			box = this._drawTextBox('left');
			this.yRuler[rowNum] = box;
		}
		rowNum++;
		var rect = this.getCellRect(rowNum+1, 1);
		rect.x += sl;
		this._setTextBox(box, rect, rowNum);
	}
	while(this.yRuler.length>rowNum){
		DomUtil.removeElement(this.yRuler.pop());
	}
}

// ┛→↓╝╘╖◤◢ ⊿   ▶◀▷ ◁▲▼△▽
AbstractArea.prototype.drawAddButton = function(){
	var sl = this.container.scrollLeft;
	var st = this.container.scrollTop;
	
	var oThis = this;
	if(this.colRulerButtonListener){
		if(!this.colRulerButton){
			this.colRulerButton = this.getRulerButton('top', '◀', '▶', this.colRulerButtonListener);
		}
		var rect = this.getCellRect(1, this.xRuler.length+2);
		rect.y += st;
		this._setTextBox(this.colRulerButton, rect, null);
	}
	if(this.rowRulerButtonListener){
		if(!this.rowRulerButton){
			this.rowRulerButton = this.getRulerButton('left', '▲', '▼', this.rowRulerButtonListener);
		}
		var rect = this.getCellRect(this.yRuler.length+2, 1);
		rect.x += sl;
		this._setTextBox(this.rowRulerButton, rect, null);
	}
	
	if(this.bothRulerButtonListener){
		if(!this.bothRulerButton){
			this.bothRulerButton = this.getRulerButton('left', '◤', '◢', this.bothRulerButtonListener);
		}
		var rect = this.getCellRect(this.yRuler.length+2, this.xRuler.length+2);

		this._setTextBox(this.bothRulerButton, rect, null);
	}
}

AbstractArea.prototype.getRulerButton = function(direct, text1, text2, fun){
	var rulerButton = this._drawTextBox(direct);
	
	var btn1 = DomUtil.newElement('span', {'class':'rulerButton'}, rulerButton);
	btn1.innerHTML = text1;
	EventUtil.addEvent(btn1, 'click', function(event){fun(event, -1);});
	
	var btn2 = DomUtil.newElement('span', {'class':'rulerButton'}, rulerButton);
	btn2.innerHTML = text2;
	EventUtil.addEvent(btn2, 'click', function(event){fun(event, 1);});
	
	return rulerButton;
}

AbstractArea.prototype._drawTextBox = function(direct, parent){
	var box = DomUtil.newElement('div', {'class':'map-rule-'+direct}, parent||this.container);
	return box;
}

AbstractArea.prototype._setTextBox = function(box, rect, text){
	box.style.top = (rect.y+'px');
	box.style.left = (rect.x+'px');
	box.style.width = (rect.width+'px');
	box.style.height = (rect.height+'px');
	box.style.lineHeight = (rect.height+'px');

	if(text){
		box.innerHTML = '<span>'+text+'</span>';
	}
}

AbstractArea.prototype.drawCells = function(){
	var itemMap = this.itemMap;
	for(key in itemMap){
		var cell = itemMap[key];
		cell.repaint();
	}
}

AbstractArea.prototype.repaint = function(){}

function HallArea(parentId, width, height){
	AbstractArea.call(this, parentId, width, height);
	
	this.paper = null;
}

Js.extend(HallArea, AbstractArea);

HallArea.prototype.repaint = function(){
	this.createElement();
	this.drawRuler();
	this.drawAddButton();
	
	this.createCanvas();
	this._drawGridBg();
	//this.getSubRegions();//画分组框(低调)
	
	this.drawCells();
}

HallArea.prototype.createCanvas = function(){
	var canvasWidth = this.width +this.cellWidth*2;
	var canvasHeight = this.height + this.cellHeight*2;
	
	if(!this.paper){
		this.paper = Raphael(this.canvasBox, canvasWidth, canvasHeight);
		this.canvasBox.className='disableSelect';
	}
	
	this.paper.clear();
	this.paper.setSize(canvasWidth, canvasHeight);
}

HallArea.prototype._drawGridBg = function(){
	var x = 0;
	var y = 0;
	var w = this.width+this.cellWidth*2;
	var h = this.height+this.cellHeight*2;
	this._drawRect(x, y, w, h, 0, {'fill-color':'#f2f2f2', 'stroke-color':'#888'});
}

HallArea.prototype._setListener = function(){
	var oThis = this;
	var element = this.canvasBox;
	
	var startPos = null;
	var endPos = null;
	
	function getOffset(event){
		return DomUtil.getOffset(event, element);
	}

	var down_fun = function(e){
		startPos = getOffset(e);
		return false;
	}

	var move_fun = function(e){
		if(oThis.onmove){
			oThis.onmove(e);
		}
		if(startPos==null){
			return;
		}
		endPos = getOffset(e);
		
		//compute
		var x = Math.min(startPos.offsetX, endPos.offsetX)+1;
		var y = Math.min(startPos.offsetY, endPos.offsetY)+1;
		var width = Math.abs(endPos.offsetX - startPos.offsetX)-2;
		var height = Math.abs(endPos.offsetY - startPos.offsetY)-2;
		
		oThis._refreshRectView(x, y, width, height);
	}

	var up_fun = function(){
		oThis._refreshRectView(null);
		
		if(startPos!=null&&endPos!=null){
			var rect = {'x':Math.min(startPos.offsetX,endPos.offsetX), 'y':Math.min(startPos.offsetY,endPos.offsetY)
					, 'width':Math.abs(startPos.offsetX-endPos.offsetX), 'height':Math.abs(startPos.offsetY-endPos.offsetY)};
			
			//deal margin
			rect.x = rect.x-oThis.cellWidth;
			rect.y = rect.y-oThis.cellHeight;
			
			if(oThis.onselect!=null){
				oThis.onselect(rect);
			}
		}
		
		startPos = null;
		endPos = null;
		
		return true;
	}
	
	var scroll_fun = function(e){
		oThis.drawRuler();
		this.container.scroll(65000, 65000);
	}
	
	element.ondragstart = new Function("return false");
	element.onselectstart = new Function("return false");
	
	EventUtil.addEvent(element, 'mousedown', down_fun);
	EventUtil.addEvent(element, 'mousemove', move_fun);
	EventUtil.addEvent(element, 'mouseup', up_fun);
	EventUtil.addEvent(this.container, 'scroll', scroll_fun);
	
	EventUtil.register('mouseup', up_fun, '1');
	//EventUtil.register('mousemove', move_fun, '2');

}

HallArea.prototype.markHead = function(x, y, w, h, show){
	var x1 = x;
	var y1 = y;
	var x2 = x1 + w;
	var y2 = y1 + h;
	var color = show?'#f00':'#000';
	var weight = show?'bold':'normal';
	
	for(var i=0;i<this.yRuler.length;i++){
		var textBox = this.yRuler[i];
		var top = parseInt(textBox.style.top);
		if(top>=y1 && top<=y2){
			textBox.style.color = color;
			textBox.style.fontWeight = weight;
			break;
		}
	}
	
	for(var i=0;i<this.xRuler.length;i++){
		var textBox = this.xRuler[i];
		var left = parseInt(textBox.style.left);
		if(left>=x1 && left<=x2){
			textBox.style.color = color;
			textBox.style.fontWeight = weight;
			break;
		}
	}
}

/*
 * attrs: stroke-width-画笔宽度, stroke-color-画笔颜色, fill-填充颜色
 */
HallArea.prototype._drawRect = function(x, y, w, h, r, attrs){
	if(!this.paper){
		return;
	}
	var rect = this.paper.rect(x, y, w, h, r);
	if(attrs){
		var pAttrs = {};
		if(attrs['fill-color']){
			pAttrs['fill'] = attrs['fill-color'];
		}
		if(attrs['stroke-color']){
			pAttrs['stroke'] = attrs['stroke-color'];
		}
		if(attrs['stroke-width']){
			pAttrs['stroke-width'] = attrs['stroke-width'];
		}
		if(attrs['fill-opacity']){
			pAttrs['fill-opacity'] = attrs['fill-opacity'];
		}
		if(attrs['stroke-dash']){
			pAttrs['stroke-dasharray'] = '-';
		}
		rect.attr(pAttrs);	
	}
	return rect;
}

HallArea.prototype._drawPath = function(path){
	this.paper.path(path).attr({'stroke-width':'1px'});
}

HallArea.prototype._drawText = function(x, y, text){
	this.paper.text(x, y, text).attr({'font-size':12, '':'', 'cursor':'pointer'});
}

HallArea.prototype._refreshRectView = function(x, y, width, height){
	//hide
	if(!x){
		if(this.rectView){
			this.rectView.remove();
		}
		this.rectView = null;
		return;
	}
	//draw
	if(!this.rectView){
		this.rectView = this.paper.rect(0, 0, 1, 1);
		this.rectView.attr({"stroke-dasharray":"-", "stroke":"#66F", "fill":"#99F", "fill-opacity":0.25});
	}

	this.rectView.attr('x', x);
	this.rectView.attr('y', y);
	this.rectView.attr('width', Math.max(width, 0));
	this.rectView.attr('height', Math.max(height, 0));
}

//@Deprecated
HallArea.prototype.drawGrid = function(){
	var gridPath = '';
	var cellWidth = this.cellWidth;
	var cellHeight = this.cellHeight;
	var xFrom = cellWidth;
	var yFrom = cellHeight;
	var xTo = this.width;
	var yTo = this.height;
	var x = xFrom;
	var y = yFrom;
	for(; y <= yTo; ){
		gridPath += ' M'+xFrom+' '+y;
		gridPath += ' L'+xTo+' '+y;
		
		y += cellHeight;
	}
	for(; x <= xTo; ){
		gridPath += ' M'+x+' '+yFrom;
		gridPath += ' L'+x+' '+yTo;

		x += cellWidth;
	}
	this._drawPath(gridPath);
}

function Sofa(){
	this.parent = null;
	this.rect = null;
	this.status = null;
	
	this.isGridItem = true;
	this.rowNum = null;
	this.colNum = null;
}

Sofa.prototype.toString = function(){
	return 'id='+this.id+',x='+this.x+',y='+this.y+',colNum='+this.colNum+',rowNum='+this.rowNum+',width='+this.width+',height='+this.height;
}

Sofa.prototype.repaint = function(){
	var cellRect;
	if(this.isGridItem){
		cellRect = this.parent.getCellRect(this.rowNum, this.colNum, this);
	}else{
		cellRect = this;
	}
	var x = this.parent.cellWidth + cellRect.x;
	var y = this.parent.cellHeight + cellRect.y;
	var w = cellRect.width;
	var h = cellRect.height;
	
	var border = Math.max(1, Math.floor(w/30));
	var radius = Math.min(w, h)/5;
	
	this.dispose();
	var paper = this.parent.paper;
	this.rect = paper.rect(x, y, w, h, radius);
	this.rect.attr({"stroke-width":border});
	if(this.virtual){
		this.rect.attr({"stroke-dasharray":"-", "stroke":"#666", "fill-opacity":0.2});
	}else{
		this.rect.attr({"stroke-dasharray":"", "stroke":"#000", "fill-opacity":1});
	}
	if(this.float){
		this.rect.attr({"fill-opacity":0.1});
	}
	if(this.selected){
		this.rect.attr({"fill":"#F00"});
	}else{
		if(this.status=="POOL"){
			this.rect.attr({"fill":"#999"});
		}else if(this.status=="SOLD"){
			this.rect.attr({"fill":"#E00"});
		}else if(this.status=="IDLE"){
			this.rect.attr({"fill":"#AA0"});
		}else{
			this.rect.attr({"fill":"#FFF"});
		}
	}
	
	var oThis = this;
	this.rect.hover(function(){
		oThis.parent.onmousein(oThis);
	}, function(){
		oThis.parent.onmouseout(oThis);
	})
}

Sofa.prototype.dispose = function(){
	if(this.rect){
		this.rect.remove();	
	}
	this.rect = null;
}

Sofa.prototype.click = function(callback){
	var oThis = this;
	var handler = function(e){
		callback(oThis, e);
	}
	this.rect.click(handler);
}

Sofa.prototype.setStatus = function(status){
	this.status = status;
	this.repaint();
}

//html5
function CanvasHallArea(parentId, width, height){
	HallArea.call(this, parentId, width, height);
}

Js.extend(CanvasHallArea, HallArea);

CanvasHallArea.prototype.createCanvas = function(){
	var canvasWidth = this.width +this.cellWidth*2;
	var canvasHeight = this.height + this.cellHeight*2;
	
	if(!this.canvasElement){
		this.canvasElement = document.createElement('canvas');
		this.canvasBox.appendChild(this.canvasElement);
		this.canvas = new Canvas(this.canvasElement);
	}
	
	this.canvasElement.width = canvasWidth;
	this.canvasElement.height = canvasHeight;
}

CanvasHallArea.prototype._drawRect = function(x, y, w, h, r, attrs){
	if(!this.canvas){
		return;
	}
	if(attrs){
		this.canvas.setAttrs(attrs);
	}
	if(r && r>0){
		this.canvas.drawRoundRect(x, y, w, h, r);
	}else{
		this.canvas.drawRect(x, y, w, h);
	}
	if(attrs && attrs['fill-color']){
        this.canvas.fill();
	}
}

CanvasHallArea.prototype._drawPath = function(path){
	this.canvas.drawPath(path);
}

CanvasHallArea.prototype._drawText = function(x, y, text){
	this.canvas.setAttrs({'fill-color':'#000', 'stroke-color':'#000'});
	this.canvas.drawText(x, y, text, 'normal 10pt Calibri');
}

CanvasHallArea.prototype._refreshRectView = function(x, y, width, height){
	//hide
	if(!x){
		if(this.rectView){
			this.rectView.style.display = 'none';
		}
		return;
	}
	
	//draw
	if(!this.rectView){
		this.rectView = document.createElement('div');
		this.rectView.style.position = 'absolute';
		this.rectView.style.margin = '0px';
		this.rectView.style.padding = '0px';
		this.rectView.style.border = 'dashed 1px #009';
		this.rectView.style.backgroundColor = '#CCF';
		this.rectView.style.filter = 'alpha(opacity : 0.5)';
		this.rectView.style.opacity = 0.5;
		this.rectView.style['z-index'] = 3;
		this.canvasBox.appendChild(this.rectView);
	}
	
	this.rectView.style.left = x+'px';
	this.rectView.style.top = y+'px';
	this.rectView.style.width = Math.max(width, 0)+'px';
	this.rectView.style.height = Math.max(height, 0)+'px';
	this.rectView.style.display = '';
}

function Seat(){
	Cell.call(this);
	this.status = 0;// 0空，1锁
	this.pStatus = 0;// 0self, 1 no
	this.color = 0;
}

Seat.colorMap = {0:'#393'};

Js.extend(Seat, Cell);

Seat.prototype.draw = function(x, y, w, h, radius, border){
	var attrs = {'stroke-dash':false, 'fill-color':"#fff", 'stroke-width':border, "stroke-color":'#000'};
	
	if(this.status==1){
		attrs["fill-color"] = '#000';
	}else if(this.status==0){
		if(this.selected){
			attrs["fill-color"] = "#EE0000";
		}else{
			attrs["fill-color"] = Seat.colorMap[this.color];
		}
	}
	if(this.selected){
		attrs["stroke-width"] = border*4;
		attrs["stroke-color"] = '#777';
	}
	
	this.parent._drawRect(x, y, w, h, radius, attrs);
	this.parent._drawText(x+(w*0.35), y+(h*0.6), this.colNum); //TOTO 字体大小	
}

